package com.example.personal.aiagent.xunfei.engine.service;

import com.example.personal.aiagent.chat.commonservice.ChatException;
import com.example.personal.aiagent.chat.commonservice.ChatService;
import com.example.personal.aiagent.chat.commonservice.ChatStatus;
import com.example.personal.aiagent.xunfei.engine.api.XunFeiApiHandler;

import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.WebSocket;

import org.springframework.stereotype.Service;

/**
 * XunfeiService
 * 讯飞服务层，当前仅支持单例
 *
 * @author blacksea3(jxt) 2023/12/3 17:46
 */
@Service
@Slf4j
public class XunFeiAbility implements ChatService {
    @Getter
    @Setter
    private ChatStatus status = ChatStatus.CLOSED;

    private XunFeiApiHandler handler;

    public static final String hostUrl = "https://spark-api.xf-yun.com/v2.1/chat";

    public static final String appid = "d4862b77";

    public static final String apiSecret = "MWNmODQyZDMwZmEyMDIwNDA4ZDNlOGI3";

    public static final String apiKey = "d19f502bc6dd17ed57030a5c0e309810";

    private String authUrl;

    private OkHttpClient client;

    private Request request;

    /**
     * 开始聊天
     */
    public void startChat() {
        log.info("start chat");
        if (status != ChatStatus.CLOSED) {
            throw new ChatException(status.name() + "not support start chat");
        }
        handler = new XunFeiApiHandler("default_user", false);
        status = ChatStatus.INIT;
        // 构建鉴权url
        try {
            authUrl = XunFeiApiHandler.getAuthUrl(hostUrl, apiKey, apiSecret);
            client = new OkHttpClient.Builder().build();
            String url = authUrl.replace("http://", "ws://").replace("https://", "wss://");
            request = new Request.Builder().url(url).build();
        } catch (Exception ex) {
            status = ChatStatus.CLOSED;
            throw new ChatException("startChat error in handler", ex);
        }
        status = ChatStatus.READY_FOR_CHAT;
    }

    /**
     * 输入聊天内容
     *
     * @param content 内容
     */
    public void inputChatContent(String content) {
        log.debug("input chat content, {}", content);
        if (status != ChatStatus.READY_FOR_CHAT) {
            throw new ChatException(status.name() + "not support input chat content");
        }

        status = ChatStatus.BUSY;
        handler.setTotalFlag(false);
        handler.setNewQuestion(content);
        handler.setTotalAnswer("");
        WebSocket webSocket = client.newWebSocket(request, handler);
        while (true) {
            // 等待web socket关闭
            try {
                Thread.sleep(3000);
                if (handler.getTotalFlag()) {
                    status = ChatStatus.READY_FOR_GET_RESULT;
                    break;
                }
            } catch (InterruptedException ex) {
                status = ChatStatus.CLOSED;
                throw new ChatException("inputChatContent error in handler", ex);
            }
        }
    }

    /**
     * 获得聊天结果
     *
     * @return 结果
     */
    public String getChatResult() {
        log.debug("get chat result");
        if (status != ChatStatus.READY_FOR_GET_RESULT) {
            throw new ChatException(status.name() + "not support get chat result");
        }

        String res = handler.getTotalAnswer();
        status = ChatStatus.READY_FOR_CHAT;
        return res;
    }

    /*
     * 关闭聊天
     */
    public void closeChat() {
        log.debug("close chat");
        if (status != ChatStatus.READY_FOR_CHAT) {
            throw new ChatException(status.name() + "not support close chat");
        }
        status = ChatStatus.CLOSING;
        handler = null;
        status = ChatStatus.CLOSED;
    }

    /**
     * 强制关闭聊天
     */
    public void forceCloseChat() {
        log.warn("force close chat");
        status = ChatStatus.CLOSING;
        handler = null;
        status = ChatStatus.CLOSED;
    }

}
